概述
上篇学习了Spring MVC ViewResolver视图解析器作用及处理流程,Spring为我们提供了丰富的视图解析器(见下图):
本系列文章是基于Spring5.0.5RELEASE。
BeanNameViewResolver
该视图解析器是根据处理器(handler)返回的逻辑视图名称,在应用上下文中查找该名称的视图bean对象(视图bean对象就是View的bean对象)。具有如下特点:
- 视图bean对象需注册在Spring应用上下中,即由托管给Spring进行管理;
- 处理器返回的逻辑视图名称为视图bean对象名称(或id);
源码
BeanNameViewResolver实现ViewResolver接口,源码如下;
public class BeanNameViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered {
// 实现Ordered接口,支持对个ViewResolver排序,值越小优先级越高
private int order = Ordered.LOWEST_PRECEDENCE;
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
/**
*实现ViewResolver接口方法
*参数viewName就是处理器返回的逻辑视图名称
*/
@Override
@Nullable
public View resolveViewName(String viewName, Locale locale) throws BeansException {
// 获取上下文
ApplicationContext context = obtainApplicationContext();
// 查找上下文中是否有“viewName”的bean定义
if (!context.containsBean(viewName)) {
if (logger.isDebugEnabled()) {
logger.debug("No matching bean found for view name '" + viewName + "'");
}
// Allow for ViewResolver chaining...
return null;
}
// 判断“viewName”的bean对象是否是View类型
if (!context.isTypeMatch(viewName, View.class)) {
if (logger.isDebugEnabled()) {
logger.debug("Found matching bean for view name '" + viewName +
"' - to be ignored since it does not implement View");
}
// Since we're looking into the general ApplicationContext here,
// let's accept this as a non-match and allow for chaining as well...
return null;
}
// 返回上下文中指定名称(或id)的View类型的bean
return context.getBean(viewName, View.class);
}
}
实战
练习BeanNameViewResolver的使用。
- 项目结构
- pom文件
通过maven构建,引入依赖的jar坐标,代码如下:
<!-- Spring MVC依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<!-- Servlet依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- JSP依赖的JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- Spring配置文件
通过此文件配置Spring MVC的组件,代码如下:
<!-- 使用默认的HandlerMapping和HandlerAdapter,指定扫描路径 -->
<context:component-scan base-package="com.github.dalianghe.controller"/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<!-- 指定ViewResolver的顺序 -->
<property name="order" value="1"/>
</bean>
<!-- 使用JstlView需引入jstl依赖 -->
<bean id="test" class="org.springframework.web.servlet.view.JstlView">
<property name="url" value="/WEB-INF/jsp/test.jsp"/>
</bean>
- 部署描述文件
配置Spring MVC核心控制器DispatcherSerlvet,代码如下:
<servlet>
<!-- Servlet名称,可任意定义,但必须与servlet-mapping中对应 -->
<servlet-name>dispatcher</servlet-name>
<!-- 指定Spring MVC核心控制类,即J2EE规范中的前端控制器(Front Controller) -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定Spring MVC配置文件,默认在WEB-INF目录下,切名字为[servlet-name]-servlet.xml,此文件中配置web相关内容,比如:指定扫描Controller路径、配置逻辑视图前缀后缀、上传文件等等 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!-- 此配置的值为正整数时,表示容器启动时初始化,即调用Servlet的init方法 -->
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<!-- 定义servlet映射 -->
<servlet-mapping>
<!-- 与servlet中servlet-name对应 -->
<servlet-name>dispatcher</servlet-name>
<!-- 映射所有的url -->
<url-pattern>/</url-pattern>
</servlet-mapping>
- 处理器
编写处理器,本例使用注解,代码如下:
@Controller
public class Demo1Controller {
@RequestMapping(value = "/beanNameViewResolver")
public String beanNameViewResolver(){
return "test";
}
}
以上例子,在Spring MVC容器中定义了BeanNameViewResolver视图解析器和id为test的InternalResourceView视图bean(可以替换),以上配置后,在handler处理器返回的逻辑视图名称为test的时候,就会使用id为test的视图bean对象(InternalResourceView)进行视图渲染。
总结
本章介绍了BeanNameViewResolver的源码及测试小例子,希望对大家有帮助。
最后创建了qq群方便大家交流,可扫描加入,同时也可加我qq:276420284,共同学习、共同进步,谢谢!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。